﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace TestConsole
{
    class Program
    {
        private readonly string  strReadonly = "str" ;

        public Program ()
        {
            //readonly 는 생성자에서 변경가능
            strReadonly = "MOD";
        }

        // EventHandler 가 Delegate  == 이벤트 리스터
        private delegate int FirstDelegate(int a, int b);

        private static int FirstMethod(int a, int b)
        {
            return a + b;
        }

        private static int SecondMethod(int a, int b)
        {
            return a + b;
        }

        private static int ThirdMethod(int a, int b)
        {
            return a + b;
        }

        private static void TestMethod(FirstDelegate fd)
        {
            Console.WriteLine(fd.Method);
        }


        static void Main(string[] args)
        {
            
            // null 가능함수
            testNull(null, 5);

            FirstDelegate fstd = FirstMethod;
            FirstDelegate fstd2 = SecondMethod;            
            FirstDelegate total = fstd + fstd2 ;

            total(1, 3);  // 3개의 메서드 실행

            TestMethod(fstd);
            
            Thread a = new Thread(AlphaMethod);
            Thread b = new Thread(BethaMethod);
            Thread c = new Thread(GammaMethod);

// 익명 delegate
            FirstDelegate f = delegate( int aa , int bb )
            {
                return aa + bb ;
            }; 


// 람다식
            FirstDelegate fa = (x,y) => x * y+y;

            List<string> list = new List<string> {"A","B","C" };
            list.Where(data => data.Contains("A"));   // "A" 을 포함하는 참인 원소들의 배열로 필터링
            
            int[] arri = { 1, 2, 3, 4, 5, 6, 7 };
            int cnti = arri.Count(n => n % 2 == 1);   // n %2 ==1 이 참인 원소들의 배열로 필터링
                
/*
            // 익명 메서드
            Thread t1 = new Thread(delegate()
            {
                for (int i = 0; i < 100; ++i)
                {
                Console.WriteLine("t111");
                }
            });
            Thread t2 = new Thread(delegate()
            {
                for (int i = 0; i < 100; ++i)
                {
                    Console.WriteLine("ttt222");
                }
            });
            Thread t3 = new Thread(delegate()
            {
                for (int i = 0; i < 100; ++i)
                {
                    Console.WriteLine("ttt333");
                }
            });
*/
            // 현재 Main Thread 가 sleep
            Thread.Sleep(100);

            

            a.Start();
            b.Start();
            c.Start();

            for (int i = 0; i < 100; ++i)
            {
                Console.WriteLine("Main");

                if (i == 30)
                {
                    // a 메서드가 쭉 먼저 실행되고, 끝나면 다른메서드 실행
                    a.Join();


                    // b 메서드 소멸
                    b.Abort();


                  
                }

            }

            // 잠시 쉬고 
            //c.Suspend();

            //다시 시작
            //Resume();

            if (a.IsAlive)
            {
                Console.WriteLine("a 살아있다.");  
            }

        }


        static void AlphaMethod()
        {
            // 이 함수 실행하는 Thread 가 Sleep
            Thread.Sleep(10000);
            for (int i = 0; i < 100; ++i)
            {
                Console.WriteLine("A");
            }
        }
        static void BethaMethod()
        {
            for (int i = 0; i < 100; ++i)
            {
                Console.WriteLine("BB");
            }
        }
        static void GammaMethod()
        {
            for (int i = 0; i < 100; ++i)
            {
                Console.WriteLine("CCC");
            }
        }




        //nullable
        private static string testNull(int? i, int abc)
        {
            // i 가 null 일수 있다.
            return "";
        }




        
    }
}
